package com.campus.food.util;

import com.campus.food.config.FileUploadConfig;
import com.campus.food.exception.BusinessException;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * 文件上传工具类
 * 
 * @author Claude3.7 Sonnet
 * @since 2025-05-29
 */
public class FileUploadUtil {
    
    /**
     * 上传文件
     * 
     * @param file 上传的文件
     * @param uploadPath 上传路径
     * @param config 文件上传配置
     * @return 文件访问URL
     */
    public static String uploadFile(MultipartFile file, String uploadPath, FileUploadConfig config) {
        // 检查文件是否为空
        if (file == null || file.isEmpty()) {
            throw new BusinessException("上传的文件不能为空");
        }
        
        // 获取文件原始名称
        String originalFilename = file.getOriginalFilename();
        if (originalFilename == null || originalFilename.isEmpty()) {
            throw new BusinessException("文件名不能为空");
        }
        
        // 检查文件类型
        String fileExtension = getFileExtension(originalFilename);
        if (!isAllowedFileType(fileExtension, config.getAllowedTypesList())) {
            throw new BusinessException("不支持的文件类型，允许的类型：" + config.getAllowedTypes());
        }
        
        // 生成文件存储路径
        String relativeFilePath = generateRelativeFilePath(originalFilename, config.isUseOriginalFilename());
        File targetDir = new File(uploadPath);
        
        // 创建目录
        if (!targetDir.exists()) {
            boolean dirCreated = targetDir.mkdirs();
            if (!dirCreated) {
                throw new BusinessException("创建目录失败: " + targetDir.getAbsolutePath());
            }
        }
        
        // 还需要创建日期目录
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        String dateDir = dateFormat.format(new Date());
        File dateDirFile = new File(uploadPath, dateDir);
        if (!dateDirFile.exists()) {
            boolean dateDirCreated = dateDirFile.mkdirs();
            if (!dateDirCreated) {
                throw new BusinessException("创建日期目录失败: " + dateDirFile.getAbsolutePath());
            }
        }
        
        // 生成完整的文件路径
        Path targetPath = Paths.get(uploadPath, relativeFilePath);
        
        try {
            // 确保目标目录存在
            Files.createDirectories(targetPath.getParent());
            
            // 保存文件
            Files.copy(file.getInputStream(), targetPath);
            
            // 返回文件访问路径
            return relativeFilePath;
        } catch (IOException e) {
            throw new BusinessException("文件上传失败：" + e.getMessage() + "，路径：" + targetPath.toString());
        }
    }
    
    /**
     * 获取文件扩展名
     * 
     * @param filename 文件名
     * @return 文件扩展名
     */
    public static String getFileExtension(String filename) {
        if (filename.lastIndexOf(".") != -1) {
            return filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();
        }
        return "";
    }
    
    /**
     * 检查文件类型是否允许
     * 
     * @param fileExtension 文件扩展名
     * @param allowedTypes 允许的文件类型列表
     * @return 是否允许
     */
    public static boolean isAllowedFileType(String fileExtension, List<String> allowedTypes) {
        return allowedTypes.contains(fileExtension.toLowerCase());
    }
    
    /**
     * 生成相对文件路径
     * 
     * @param originalFilename 原始文件名
     * @param useOriginalFilename 是否使用原始文件名
     * @return 相对文件路径
     */
    public static String generateRelativeFilePath(String originalFilename, boolean useOriginalFilename) {
        // 生成日期目录
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        String dateDir = dateFormat.format(new Date());
        
        // 获取文件扩展名
        String fileExtension = getFileExtension(originalFilename);
        
        // 生成文件名
        String filename;
        if (useOriginalFilename) {
            // 使用原始文件名
            filename = System.currentTimeMillis() + "_" + originalFilename;
        } else {
            // 使用UUID作为文件名
            filename = UUID.randomUUID().toString().replace("-", "") + "." + fileExtension;
        }
        
        // 返回相对路径
        return dateDir + File.separator + filename;
    }
    
    /**
     * 删除文件
     * 
     * @param filePath 文件路径
     * @param basePath 基础路径
     * @return 是否删除成功
     */
    public static boolean deleteFile(String filePath, String basePath) {
        if (filePath == null || filePath.isEmpty()) {
            return false;
        }
        
        Path path = Paths.get(basePath, filePath);
        try {
            return Files.deleteIfExists(path);
        } catch (IOException e) {
            return false;
        }
    }
} 